使用 Select 元件時,一般基本的使用如下,提供一個清單作為選單顯示:
<script setup>
import { ref } from "vue";
const selectedCity = ref();
const cities = ref([
{ name: 'New York', code: 'NY' },
{ name: 'Rome', code: 'RM' },
{ name: 'London', code: 'LDN' },
{ name: 'Istanbul', code: 'IST' },
{ name: 'Paris', code: 'PRS' }
]);
</script>
<template>
<main class="p-6">
<div class="grid grid-cols-4 gap-4">
<Select v-model="selectedCity" :options="cities" optionLabel="name" placeholder="Select a City" fluid />
</div>
</main>
</template>
接觸 PrimeVue 時有遇到 Select 好用的 props 功能或使用上小細節,記錄如下:
labe for 與 input id 的對應:
在元件上若要與 label 連動,須使用 inputId 屬性,無法直接使用 id。點擊 label 才會正確連動到 Select 上,以下範例為點擊 label 後 Select 正確加上 focus 的效果。
<label for="city" class="inline-block mb-1">City</label>
(o) <Select inputId="city" v-model="selectedCity" :options="cities" optionLabel="name" placeholder="Select a City" fluid />
(x) <Select id="city" v-model="selectedCity" :options="cities" optionLabel="name" placeholder="Select a City" fluid />
Filter
在選單較多的情況下較難瀏覽,Select 提供 Filter 屬性,提供篩選輸入框方便使用者登打搜尋。
<!-- 加上 filter 屬性 -->
<Select inputId="city" v-model="selectedCity" filter :options="cities" optionLabel="name" placeholder="Select a City" fluid />
清除選取結果
通常要移除選取結果,除了可加上預設選項外,Select 還加上 showClear 屬性,在清除已選取的結果上可更方便操作。
<!-- 加上 showClear 屬性 -->
<Select inputId="city" v-model="selectedCity" filter showClear :options="cities" optionLabel="name" placeholder="Select a City" fluid />
Loading 狀態
若 Select 選單是由 API 回傳的結果,可在 Select 上加上 loading 屬性,在 API 回傳結果前設定 loading 為 true,直到回傳後更改為 false 停止 loading 狀態,防止使用者看到空的選單,提升使用者體驗。
<script setup>
import { onMounted, ref } from "vue";
const loading = ref(true);
onMounted(() => {
setTimeout(() => {
loading.value = false; // 假設 5 秒後回傳
}, 5000)
})
</script>
<template>
<Select inputId="city" v-model="selectedCity" filter showClear :loading="loading" :options="cities" optionLabel="name" placeholder="Select a City" fluid />
</template>
客製 label 與 value 內容
在 Select 設定中,可設定 label 及 value 的屬性為 optionLabel 及 optionValue。若皆無指定,其值皆為選單陣列內的物件值。
{{ selectedCity }} <br />
<label for="city" class="inline-block mb-1">City</label>
<Select
inputId="city"
v-model="selectedCity"
filter
showClear
:loading="loading"
:options="cities"
placeholder="Select a City"
fluid
/>
若指定 optionLabel 及 optionValue 屬性為特定物件的 key,則結果如下:
{{ selectedCity }} <br />
<label for="city" class="inline-block mb-1">City</label>
<Select
inputId="city"
v-model="selectedCity"
filter
showClear
:loading="loading"
:options="cities"
optionLabel="name" // 設定 label
optionValue="code" // 設定 value
placeholder="Select a City"
fluid
/>
其中在 API 文件上提及 optionLabel 及 optionValue 也可傳入函式,如此可更能客製化 label 及 value。
範例如下:
<script setup>
...
const setLabel = (data) => {
return `${data.name}(${data.code})`;
}
const setValue = (data) => {
return `city-${data.code}`;
}
</script>
<template>
{{ selectedCity }} <br />
<label for="city" class="inline-block mb-1">City</label>
<Select
inputId="city"
v-model="selectedCity"
filter
showClear
:loading="loading"
:options="cities"
:optionLabel="setLabel" // 客製 label
:optionValue="setValue" // 客製 value
placeholder="Select a City"
fluid
/>
</template>
參考連結:https://primevue.org/select/